import axios from 'axios'

interface CoinMarketCapResponse {
  data: {
    NEAR: {
      quote: {
        KRW: {
          price: number
          percent_change_24h: number
          volume_24h: number
          market_cap: number
        }
      }
    }
  }
}

interface PriceData {
  price: number
  change24h: number
  changeRate24h: number
  volume24h: number
  lastUpdate: number
}

/**
 * NEAR价格服务 - 从CoinMarketCap获取实时价格
 */
class PriceService {
  private apiKey: string | null
  private baseUrl: string = 'https://pro-api.coinmarketcap.com/v1'
  private cache: PriceData | null = null
  private cacheExpiry: number = 0
  private cacheDuration: number = 5 * 60 * 1000 // 5分钟缓存 (增加缓存时间以确保价格一致性)
  private lastSuccessfulPrice: number | null = null // 最后一次成功获取的价格(用于降级)
  private defaultFallbackPrice: number = 5000 // 默认降级价格(5000 KRW)

  constructor() {
    // 从环境变量读取API Key
    this.apiKey = process.env.COINMARKETCAP_API_KEY || null
  }

  /**
   * 构造降级价格数据，统一处理缺少 API Key 或请求失败的情况
   */
  private getFallbackPrice(now: number, reason: string): PriceData {
    console.warn(`⚠️ ${reason}`)

    // 降级策略1: 使用过期缓存
    if (this.cache) {
      console.warn(`만료된 캐시 가격 사용: ₩${this.cache.price.toFixed(2)} (마지막 업데이트: ${new Date(this.cache.lastUpdate).toLocaleString('ko-KR')})`)
      return this.cache
    }

    // 降级策略2: 使用最后成功价格
    if (this.lastSuccessfulPrice) {
      console.warn(`마지막 성공 가격 사용: ₩${this.lastSuccessfulPrice.toFixed(2)}`)
      const fallbackData: PriceData = {
        price: this.lastSuccessfulPrice,
        change24h: 0,
        changeRate24h: 0,
        volume24h: 0,
        lastUpdate: now
      }
      this.cache = fallbackData
      this.cacheExpiry = now + this.cacheDuration
      return fallbackData
    }

    // 降级策略3: 使用默认价格
    console.error(`⚠️ 기본 대체 가격 사용: ₩${this.defaultFallbackPrice.toFixed(2)}`)
    const defaultData: PriceData = {
      price: this.defaultFallbackPrice,
      change24h: 0,
      changeRate24h: 0,
      volume24h: 0,
      lastUpdate: now
    }
    this.cache = defaultData
    this.cacheExpiry = now + this.cacheDuration
    return defaultData
  }

  /**
   * 获取NEAR当前价格(KRW)
   */
  async getNearPrice(): Promise<number> {
    const priceData = await this.getNearPriceData()
    return priceData.price
  }

  /**
   * 获取NEAR完整价格数据
   * 包含重试机制和多层降级策略
   */
  async getNearPriceData(): Promise<PriceData> {
    const now = Date.now()

    // 检查缓存
    if (this.cache && now < this.cacheExpiry) {
      return this.cache
    }

    if (!this.apiKey) {
      return this.getFallbackPrice(now, 'COINMARKETCAP_API_KEY 未配置, 사용 가능한 대체 가격으로 동작합니다')
    }

    // 尝试获取价格,最多重试3次
    const maxRetries = 3
    const retryDelay = 2000 // 2秒

    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        console.log(`尝试获取NEAR价格... (${attempt}/${maxRetries})`)

        const response = await axios.get<CoinMarketCapResponse>(
          `${this.baseUrl}/cryptocurrency/quotes/latest`,
          {
            params: {
              symbol: 'NEAR',
              convert: 'KRW'
            },
            headers: {
              'X-CMC_PRO_API_KEY': this.apiKey,
              'Accept': 'application/json'
            },
            timeout: 10000 // 增加到10秒超时
          }
        )

        const nearData = response.data.data.NEAR
        const krwQuote = nearData.quote.KRW

        this.cache = {
          price: krwQuote.price,
          change24h: krwQuote.price * (krwQuote.percent_change_24h / 100),
          changeRate24h: krwQuote.percent_change_24h,
          volume24h: krwQuote.volume_24h,
          lastUpdate: now
        }
        this.cacheExpiry = now + this.cacheDuration
        this.lastSuccessfulPrice = krwQuote.price // 保存最后成功价格

        console.log(`✅ NEAR 가격 업데이트 성공: ₩${this.cache.price.toFixed(2)}`)
        return this.cache

      } catch (error) {
        console.error(`❌ CoinMarketCap API 호출 실패 (시도 ${attempt}/${maxRetries}):`, error instanceof Error ? error.message : error)

        // 如果不是最后一次重试,等待后继续
        if (attempt < maxRetries) {
          console.log(`${retryDelay}ms 후 재시도...`)
          await new Promise(resolve => setTimeout(resolve, retryDelay))
          continue
        }

        // 最后一次重试失败,使用降级策略
        console.warn('⚠️ 모든 재시도 실패, 대체 가격 사용')
        return this.getFallbackPrice(now, '모든 재시도 실패, 대체 가격 사용')
      }
    }

    // 理论上不会到达这里,但为了类型安全
    throw new Error('NEAR 가격을 가져올 수 없습니다.')
  }

  /**
   * 清除缓存(用于强制刷新)
   */
  clearCache(): void {
    this.cache = null
    this.cacheExpiry = 0
  }

  /**
   * 将KRW金额转换为NEAR数量
   */
  async convertKrwToNear(krwAmount: number): Promise<number> {
    const price = await this.getNearPrice()
    return krwAmount / price
  }

  /**
   * 将NEAR数量转换为KRW金额
   */
  async convertNearToKrw(nearAmount: number): Promise<number> {
    const price = await this.getNearPrice()
    return nearAmount * price
  }

  /**
   * 获取历史价格数据
   * 注意: CoinMarketCap 免费API不提供历史K线数据,这里基于当前价格生成模拟历史数据
   * 如需真实历史数据,需要升级到付费API计划
   */
  async getPriceHistory(period: '1h' | '24h' | '7d' | '30d'): Promise<Array<{ time: string; price: number; volume: number }>> {
    const currentPriceData = await this.getNearPriceData()
    const currentPrice = currentPriceData.price
    const historyData: Array<{ time: string; price: number; volume: number }> = []

    let dataPoints = 24
    let intervalMinutes = 60
    let dateFormat: 'time' | 'date' = 'time'

    switch (period) {
      case '1h':
        dataPoints = 60
        intervalMinutes = 1
        break
      case '24h':
        dataPoints = 24
        intervalMinutes = 60
        break
      case '7d':
        dataPoints = 42 // 7天 x 6个点/天
        intervalMinutes = 240 // 4小时
        break
      case '30d':
        dataPoints = 30
        intervalMinutes = 1440 // 1天
        dateFormat = 'date'
        break
    }

    const now = Date.now()

    // 生成基于当前价格的历史数据（模拟价格波动）
    for (let i = dataPoints - 1; i >= 0; i--) {
      const timestamp = now - i * intervalMinutes * 60 * 1000
      const date = new Date(timestamp)

      // 模拟价格波动 (±5%)
      const priceVariation = 1 + (Math.random() - 0.5) * 0.1
      const price = Math.round(currentPrice * priceVariation * 100) / 100

      // 模拟交易量
      const volume = Math.random() * 10000

      let timeLabel = ''
      if (dateFormat === 'time') {
        timeLabel = date.toTimeString().slice(0, 5) // HH:MM
      } else {
        timeLabel = `${date.getMonth() + 1}/${date.getDate()}` // MM/DD
      }

      historyData.push({
        time: timeLabel,
        price,
        volume
      })
    }

    return historyData
  }
}

// 创建全局实例
export const priceService = new PriceService()
